package com.chenfan.mcn.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chenfan.common.exception.BusinessException;
import com.chenfan.mcn.clients.baseinfo.BaseCustomer;
import com.chenfan.mcn.clients.baseinfo.BaseInfoClient;
import com.chenfan.mcn.clients.finance.ClearData4ExecuteOrderVo;
import com.chenfan.mcn.clients.finance.FinanceClient;
import com.chenfan.mcn.clients.privilege.DepartmentVO;
import com.chenfan.mcn.clients.privilege.PrivilegeClient;
import com.chenfan.mcn.clients.privilege.SUser;
import com.chenfan.mcn.constant.DictTypeCst;
import com.chenfan.mcn.dao.AeExcutorConfirmMapper;
import com.chenfan.mcn.dao.AeQuarterlyTableMapper;
import com.chenfan.mcn.dao.AeRoyaltiesMapper;
import com.chenfan.mcn.enums.*;
import com.chenfan.mcn.exception.McnErrorCode;
import com.chenfan.mcn.extension.excel.ExcelUtils;
import com.chenfan.mcn.model.*;
import com.chenfan.mcn.model.common.PageInfo;
import com.chenfan.mcn.model.dto.*;
import com.chenfan.mcn.model.vo.AeExecutorConfirmVO;
import com.chenfan.mcn.model.vo.AeQuarterlyTableVO;
import com.chenfan.mcn.model.vo.AeRoyaltiesVO;
import com.chenfan.mcn.model.vo.AeRoyaltiesVoV2;
import com.chenfan.mcn.service.*;
import com.chenfan.mcn.utils.BusinessAssert;
import com.chenfan.mcn.utils.CommonUtil;
import com.chenfan.mcn.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author chenguopeng
 * @Date 2021/6/7 15:53
 */
@Service
@Slf4j
public class AeRoyaltiesServiceImpl extends ServiceImpl<AeRoyaltiesMapper, AeRoyalties> implements AeRoyaltiesService {

    @Autowired
    private ContractExcutionOrderService contractExcutionOrderService;

    @Autowired
    private AeQuarterlyTableMapper aeQuarterlyTableMapper;

    @Autowired
    private ApprovalFlowService approvalFlowService;

    @Autowired
    private PrivilegeClient privilegeClient;

    @Autowired
    private AeExcutorConfirmMapper aeExcutorConfirmMapper;

    @Autowired
    private AeExcutorConfirmService aeExcutorConfirmService;

    @Autowired
    private BaseInfoClient baseInfoClient;

    @Autowired
    private FinanceClient financeClient;

    @Autowired
    private StarPlatformInfoService starPlatformInfoService;

    @Autowired
    private BrandInfoService brandInfoService;

    @Override
    public PageInfo<AeRoyaltiesVO> getPage(AeRoyaltiesDTO dto, Integer status) {
        Page<AeRoyaltiesVO> dataList = null;
        if (status.equals(AeQuarterlyTypeEnum.YZF_CONTRACT.getCode())) {
            dataList = this.baseMapper.invalidList(new Page<>(dto.getPageNum(), dto.getPageSize()), dto);
        } else {
            dataList = this.baseMapper.pageInfo(new Page<>(dto.getPageNum(), dto.getPageSize()), dto);
        }
        if(Objects.nonNull(dataList) && CollectionUtils.isNotEmpty(dataList.getRecords())) {
            List<String> brandCodes = dataList.getRecords().stream().map(AeRoyaltiesVO::getBrandName).filter(Objects::nonNull).distinct().collect(Collectors.toList());
            Map<String,String> brandMap = brandInfoService.getBrandMapByCodes(brandCodes);
            dataList.getRecords().forEach(e -> {
                if(brandMap.containsKey(e.getBrandName())) {
                    e.setBrandNameN(brandMap.get(e.getBrandName()));
                }
            });
        }
        return PageInfo.toPageInfo(dataList);
    }

    @Override
    public void assembleExportData(List<AeRoyaltiesVoV2> exportList) {
        if(CollectionUtils.isEmpty(exportList)) {
            return;
        }
        DateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
        List<Long> userIdList = new ArrayList<>();
        //获取执行统筹人信息
        List<Long> coordinatorIdList = exportList.stream().map(AeRoyaltiesVoV2::getCoordinatorId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        if(CollUtil.isNotEmpty(coordinatorIdList)) {
            userIdList.addAll(coordinatorIdList);
        }
        //获取执行人信息
        List<Long> excutorIdList = exportList.stream().map(AeRoyaltiesVoV2::getExcutorId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        if(CollUtil.isNotEmpty(excutorIdList)) {
            userIdList.addAll(excutorIdList);
        }
        if(CollUtil.isNotEmpty(userIdList)) {
            Map<Long, SUser> sUserMap = CommonUtil.defaultList(privilegeClient.getUserByIds(userIdList).getObj()).stream().collect(Collectors.toMap(SUser::getUserId, Function.identity()));
            exportList.forEach(x -> {
                if(CommonUtil.containsKey(sUserMap, x.getCoordinatorId())) {
                    SUser sUser = sUserMap.get(x.getCoordinatorId());
                    x.setCoordinatorNumber(sUser.getJobNumber());
                    x.setCoordinatorName(sUser.getUsername());
                }
                if(CommonUtil.containsKey(sUserMap, x.getExcutorId())) {
                    SUser sUser = sUserMap.get(x.getExcutorId());
                    x.setJobNumber(sUser.getJobNumber());
                    x.setExcutorName(sUser.getUsername());
                }
            });
        }
        //财务数据转换
        List<String> excuteCodes = exportList.stream().map(AeRoyaltiesVoV2::getExcuteCode).collect(Collectors.toList());
        Map<String, ClearData4ExecuteOrderVo> clearData4ExecuteOrderMap = financeClient.clearData4ExecuteOrder(excuteCodes).getObj();
        exportList.forEach(x -> {
            // 财务数据转换
            ClearData4ExecuteOrderVo clearData4ExecuteOrderVo = clearData4ExecuteOrderMap.get(x.getExcuteCode());
            if (Objects.nonNull(clearData4ExecuteOrderVo)) {
                if (StringUtils.isNotBlank(clearData4ExecuteOrderVo.getArapDate())) {
                    String maxPaybackDate = getMaxDate(Arrays.asList(clearData4ExecuteOrderVo.getArapDate().split(",")));
                    x.setPaybackDate(maxPaybackDate);
                }
                if (StringUtils.isNotBlank(clearData4ExecuteOrderVo.getClearDate())) {
                    String maxClearDate = getMaxDate(Arrays.asList(clearData4ExecuteOrderVo.getClearDate().split(",")));
                    if (StringUtils.isNotBlank(maxClearDate) && StringUtils.isNotBlank(x.getRealPublishDate())) {
                        x.setPaidAccountPeriod(String.valueOf(DateUtil.getPhaseDifference(x.getRealPublishDate(), maxClearDate, dft)));
                    }
                    x.setClearDate(maxClearDate);
                }
            }
        });
        List<Long> customerIdList = exportList.stream().map(AeRoyaltiesVoV2::getCustomerId).distinct().collect(Collectors.toList());
        Map<Long, BaseCustomer> customerMapping = Objects.requireNonNull(baseInfoClient.getMcnCustomerByIds(customerIdList)).getObj();
        //查询平台名称
        List<Long> starPlatInfoIds = exportList.stream().map(AeRoyaltiesVoV2::getStarPlatformInfoId).collect(Collectors.toList());
        Map<Long, StarPlatformInfo> starPlatformInfoMap = CommonUtil.defaultList(starPlatformInfoService.selectBatchIds(starPlatInfoIds))
                .stream().collect(Collectors.toMap(StarPlatformInfo::getId, Function.identity()));
        List<String> brandCodes = exportList.stream().map(AeRoyaltiesVoV2::getBrandName).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        Map<String,String> brandMap = brandInfoService.getBrandMapByCodes(brandCodes);
        Map<String, Map<String, String>> secondlevelDictMap = baseInfoClient.getAllSecondlevelDictMap(DictTypeCst.PUBLISHING_PLATFORM);
        exportList.forEach(x -> {
            if (starPlatformInfoMap.containsKey(x.getStarPlatformInfoId())) {
                StarPlatformInfo starPlatformInfo = starPlatformInfoMap.get(x.getStarPlatformInfoId());
                x.setPlatformName(starPlatformInfo.getPlatformName());
                if (StringUtils.isNotBlank(x.getPublishForm())) {
                    x.setPublishFormName(CommonUtil.getMapValue(secondlevelDictMap.get(starPlatformInfo.getPlatformId()), x.getPublishForm()));
                }
            }
            if(brandMap.containsKey(x.getBrandName())) {
                x.setBrandNameN(brandMap.get(x.getBrandName()));
            }
            x.setContractTypeName(IncomeContractTypeEnum.getContractTypeName(x.getContractType()));
            x.setApprovalStatusName(ExcutionApprovalStatusEnum.getStatusName(x.getApprovalStatus()));
        });
        exportList.forEach(y -> y.setCustomerName(customerMapping.get(y.getCustomerId()).getCustomerNameC()));
    }

    private String getMaxDate(List<String> dteStrList) {
        String max = "";
        if (dteStrList.size() > 1) {
            for (String dateStr : dteStrList) {
                int compareTo = max.compareTo(dateStr);
                if (compareTo <= 0) {
                    max = dateStr;
                }
            }
        } else {
            max = dteStrList.get(0);
        }
        return max;
    }

    @Override
    public JSONObject getPageView(AeRoyaltiesDTO aeRoyaltiesDTO) {
        DateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
        Assert.notNull(aeRoyaltiesDTO.getAeQuarterlyId(), McnErrorCode.AE_QUARTERLY_ID_IS_NULL.message());
        // 季度单
        AeQuarterlyTable aeQuarterlyTable = aeQuarterlyTableMapper.selectById(aeRoyaltiesDTO.getAeQuarterlyId());
        verifyAePopup(aeRoyaltiesDTO, aeQuarterlyTable);
        PageInfo<AeRoyaltiesVoV2> pageInfo = PageInfo.toPageInfo(this.baseMapper.getContractExcutionOrders(new Page<>(aeRoyaltiesDTO.getPageNum(), aeRoyaltiesDTO.getPageSize()), aeRoyaltiesDTO));
        if (CollUtil.isNotEmpty(pageInfo.getList())) {
            List<AeRoyaltiesVoV2> aeRoyaltiesVoV2s = pageInfo.getList();
            //获取执行统筹人信息
            List<Long> coordinatorIdList = aeRoyaltiesVoV2s.stream().map(AeRoyaltiesVoV2::getCoordinatorId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
            if(CollUtil.isNotEmpty(coordinatorIdList)) {
                List<SUser> sUserList = privilegeClient.getUserByIds(coordinatorIdList).getObj();
                Map<Long, String> sUserNameMap = CommonUtil.getIfNecessary(CollUtil.isNotEmpty(sUserList),
                        () -> sUserList.stream().collect(Collectors.toMap(k -> k.getUserId(), v -> v.getJobNumber())), Collections.EMPTY_MAP);
                aeRoyaltiesVoV2s.forEach(x -> {
                    x.setCoordinatorNumber(sUserNameMap.get(x.getCoordinatorId()));
                });
            }
            //财务数据转换
            List<String> excuteCodes = aeRoyaltiesVoV2s.stream().map(AeRoyaltiesVoV2::getExcuteCode).collect(Collectors.toList());
            Map<String, ClearData4ExecuteOrderVo> clearData4ExecuteOrderMap = financeClient.clearData4ExecuteOrder(excuteCodes).getObj();
            aeRoyaltiesVoV2s.forEach(x -> {
                // 财务数据转换
                ClearData4ExecuteOrderVo clearData4ExecuteOrderVo = clearData4ExecuteOrderMap.get(x.getExcuteCode());
                if (Objects.nonNull(clearData4ExecuteOrderVo)) {
                    if (StringUtils.isNotBlank(clearData4ExecuteOrderVo.getArapDate())) {
                        String maxPaybackDate = getMaxDate(Arrays.asList(clearData4ExecuteOrderVo.getArapDate().split(",")));
                        x.setPaybackDate(maxPaybackDate);
                    }
                    if (StringUtils.isNotBlank(clearData4ExecuteOrderVo.getClearDate())) {
                        String maxClearDate = getMaxDate(Arrays.asList(clearData4ExecuteOrderVo.getClearDate().split(",")));
                        if (StringUtils.isNotBlank(maxClearDate) && StringUtils.isNotBlank(x.getRealPublishDate())) {
                            x.setPaidAccountPeriod(String.valueOf(DateUtil.getPhaseDifference(x.getRealPublishDate(), maxClearDate, dft)));
                        }
                        x.setClearDate(maxClearDate);
                    }
                }
            });
            List<Long> customerIdList = aeRoyaltiesVoV2s.stream().map(AeRoyaltiesVoV2::getCustomerId).distinct().collect(Collectors.toList());
            Map<Long, BaseCustomer> customerMapping = Objects.requireNonNull(baseInfoClient.getMcnCustomerByIds(customerIdList)).getObj();
            //查询平台名称
            List<Long> starPlatInfoIds = aeRoyaltiesVoV2s.stream().map(AeRoyaltiesVoV2::getStarPlatformInfoId).collect(Collectors.toList());
            Map<Long, StarPlatformInfo> starPlatformInfoMap = CommonUtil.defaultList(starPlatformInfoService.selectBatchIds(starPlatInfoIds))
                    .stream().collect(Collectors.toMap(StarPlatformInfo::getId, Function.identity()));
            List<String> brandCodes = aeRoyaltiesVoV2s.stream().map(AeRoyaltiesVoV2::getBrandName).filter(Objects::nonNull).distinct().collect(Collectors.toList());
            Map<String,String> brandMap = brandInfoService.getBrandMapByCodes(brandCodes);
            Map<String, Map<String, String>> secondlevelDictMap = baseInfoClient.getAllSecondlevelDictMap(DictTypeCst.PUBLISHING_PLATFORM);
            if (aeRoyaltiesVoV2s.size() > 0) {
                aeRoyaltiesVoV2s.forEach(x -> {
                    if (starPlatformInfoMap.containsKey(x.getStarPlatformInfoId())) {
                        StarPlatformInfo starPlatformInfo = starPlatformInfoMap.get(x.getStarPlatformInfoId());
                        x.setPlatformName(starPlatformInfo.getPlatformName());
                        if (StringUtils.isNotBlank(x.getPublishForm())) {
                            x.setPublishFormName(CommonUtil.getMapValue(secondlevelDictMap.get(starPlatformInfo.getPlatformId()), x.getPublishForm()));
                        }
                    }
                    if(brandMap.containsKey(x.getBrandName())) {
                        x.setBrandNameN(brandMap.get(x.getBrandName()));
                    }
                    x.setContractTypeName(IncomeContractTypeEnum.getContractTypeName(x.getContractType()));
                });
                aeRoyaltiesVoV2s.forEach(y -> y.setCustomerName(customerMapping.get(y.getCustomerId()).getCustomerNameC()));
            }
        }
        // 用户信息
        String userName;
        Long userId;
        if (Objects.nonNull(aeRoyaltiesDTO.getType())) {
            // 弹框
            userId = aeRoyaltiesDTO.getExcutorId();
            SUser sUser = Objects.requireNonNull(privilegeClient.getUserById(aeRoyaltiesDTO.getExcutorId())).getObj();
            userName = sUser.getUsername();
            // isConfirmed(aeRoyaltiesDTO, aeQuarterlyTable);
        } else {
            // 列表
            userName = aeQuarterlyTable.getCreateName();
            userId = aeQuarterlyTable.getCreateBy();
        }
        // 部门信息
        Map<Long, DepartmentVO> sDepartmentMap =
                Objects.requireNonNull(privilegeClient.getDepartmentHeadByUserIds(Collections.singletonList(userId))).getObj();
        DepartmentVO sDepartment = sDepartmentMap.get(userId);
        String departmentName = Objects.nonNull(sDepartment) ? sDepartment.getDepartmentName() : null;
        // 封装基本信息
        AeQuarterlyTableVO aeQuarterlyTableVO = new AeQuarterlyTableVO(userName, departmentName, aeRoyaltiesDTO.getType());
        BeanUtils.copyProperties(aeQuarterlyTable, aeQuarterlyTableVO);
        // 封装返回值
        JSONObject result = new JSONObject();

        result.put("page", pageInfo);
        result.put("baseInfo", aeQuarterlyTableVO);
        return result;
    }

    private void verifyAePopup(AeRoyaltiesDTO aeRoyaltiesDTO, AeQuarterlyTable aeQuarterlyTable) {
        if (Objects.nonNull(aeRoyaltiesDTO.getType())) {
            if (aeQuarterlyTable.getStatus().equals(AeQuarterlyTypeEnum.YZF_CONTRACT.getCode())) {
                throw new BusinessException(McnErrorCode.AE_INVALID);
            }
        }
    }

    @Override
    public JSONObject getAeDetail(AeDetailDTO aeDetailDTO) {
        Assert.notNull(aeDetailDTO.getAeQuarterlyId(), McnErrorCode.AE_QUARTERLY_ID_IS_NULL.message());
        AeQuarterlyTable aeQuarterlyTable = aeQuarterlyTableMapper.selectById(aeDetailDTO.getAeQuarterlyId());
        Assert.notNull(aeQuarterlyTable, McnErrorCode.AE_CANNOT_IS_NULL.message());
        QueryWrapper<AeRoyalties> queryWrapper = new QueryWrapper<>();
        List<AeRoyalties> aeRoyalties = getAeDetailList(aeQuarterlyTable, queryWrapper, aeDetailDTO);
        List<Long> executorIdList = aeRoyalties.stream().map(AeRoyalties::getExcutorId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<Long> depPrincipalNameIdList = aeRoyalties.stream().map(AeRoyalties::getDepPrincipalNameId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        McnPage<AeExcutorConfirm> mcnPage = new McnPage<>();
        mcnPage.setPageNum(aeDetailDTO.getPageNum()).setPageSize(aeDetailDTO.getPageSize());
        Page<AeExcutorConfirm> page = new Page<>();
        if (executorIdList.size() > 0) {
            page = aeExcutorConfirmMapper.getAeExecutorConfirmList(mcnPage, aeDetailDTO.getAeQuarterlyId(), executorIdList, depPrincipalNameIdList);
        }
        //分页
        PageInfo<AeExecutorConfirmVO> pageInfo = PageInfo.toPageInfo(page, AeExecutorConfirmVO.class);
        if (!CollectionUtils.isEmpty(page.getRecords())) {
            setRoyaltyAmount(pageInfo, aeQuarterlyTable);
            // 部门信息
            List<Long> executorIds = page.getRecords().stream().map(AeExcutorConfirm::getExcutorId).collect(Collectors.toList());
            Map<Long, DepartmentVO> voMap = Objects.requireNonNull(privilegeClient.getDepartmentHeadByUserIds(executorIds)).getObj();
            if (Objects.nonNull(pageInfo.getList())) {
                pageInfo.getList().forEach(aeExecutorConfirm -> {
                    // 插入部门名称
                    if (voMap.containsKey(aeExecutorConfirm.getExcutorId())) {
                        aeExecutorConfirm
                                .setDepartmentName(voMap.get(aeExecutorConfirm.getExcutorId()).getDepartmentName());
                        aeExecutorConfirm.setExcutorName(voMap.get(aeExecutorConfirm.getExcutorId()).getUsername());
                    }
                });
            }
        }
        // 封装基本信息
        AeQuarterlyTableVO aeQuarterlyTableVO = new AeQuarterlyTableVO();
        BeanUtils.copyProperties(aeQuarterlyTable, aeQuarterlyTableVO);
        aeQuarterlyTableVO.setName(aeQuarterlyTable.getCreateName());
        // 封装返回值
        JSONObject result = new JSONObject();
        result.put("page", pageInfo);
        result.put("baseInfo", aeQuarterlyTableVO);
        return result;
    }

    private List<AeRoyalties> getAeDetailList(AeQuarterlyTable aeQuarterlyTable, QueryWrapper<AeRoyalties> queryWrapper, AeDetailDTO aeDetailDTO) {
        if (aeQuarterlyTable.getStatus().equals(AeQuarterlyTypeEnum.YZF_CONTRACT.getCode())) {
            queryWrapper.lambda().eq(AeRoyalties::getAeQuarterlyId, aeQuarterlyTable.getId()).eq(AeRoyalties::getIsInvalid, AeCommonEnum.IS_INVALID.getCode());
        } else {
            queryWrapper.lambda().eq(AeRoyalties::getAeQuarterlyId, aeQuarterlyTable.getId()).eq(AeRoyalties::getIsDelete, AeCommonEnum.DATA_NOT_DELETE.getCode());
        }
        return this.baseMapper.selectList(queryWrapper);
    }

    private void setRoyaltyAmount(PageInfo<AeExecutorConfirmVO> pageInfo, AeQuarterlyTable aeQuarterlyId) {
//        Map<Long, BigDecimal> depPrincipalMoneyMap = new HashMap<>(16);
//        Map<Long, BigDecimal> executorMoneyMap = new HashMap<>(16);
        List<Long> executorIdList = pageInfo.getList().stream().map(AeExecutorConfirmVO::getExcutorId).distinct().collect(Collectors.toList());
        List<SUser> sUsers = Objects.requireNonNull(privilegeClient.getUserByIds(executorIdList)).getObj();
        Map<Long, String> sUserMap = sUsers.stream().collect(Collectors.toMap(SUser::getUserId, SUser::getJobNumber));
//        List<Long> executorIds = pageInfo.getList().stream().filter(x -> x.getType() == 1).map(AeExecutorConfirmVO::getExcutorId).distinct().collect(Collectors.toList());
//        List<Long> departmentHeaderIds = pageInfo.getList().stream().filter(x -> x.getType() == 2).map(AeExecutorConfirmVO::getExcutorId).distinct().collect(Collectors.toList());
//        List<AeRoyalties> depPrincipalMoney;
//        if (departmentHeaderIds.size() > 0) {
//            if (aeQuarterlyId.getStatus().equals(AeQuarterlyTypeEnum.YZF_CONTRACT.getCode())) {
//                depPrincipalMoney = aeExcutorConfirmMapper.getDepPrincipalMoneyInvalid(aeQuarterlyId.getId(), departmentHeaderIds);
//            } else {
//                depPrincipalMoney = aeExcutorConfirmMapper.getDepPrincipalMoney(aeQuarterlyId.getId(), departmentHeaderIds);
//            }
//            depPrincipalMoneyMap = depPrincipalMoney.stream().collect(Collectors.toMap(AeRoyalties::getDepPrincipalNameId, AeRoyalties::getDepPrincipalMoney));
//        }
//        List<AeRoyalties> executorTotalMoney;
//        if (executorIds.size() > 0) {
//            if (aeQuarterlyId.getStatus().equals(AeQuarterlyTypeEnum.YZF_CONTRACT.getCode())) {
//                executorTotalMoney = aeExcutorConfirmMapper.getExecutorTotalMoneyInvalid(aeQuarterlyId.getId(), executorIds);
//            } else {
//                executorTotalMoney = aeExcutorConfirmMapper.getExecutorTotalMoney(aeQuarterlyId.getId(), executorIds);
//            }
//            executorMoneyMap = executorTotalMoney.stream().collect(Collectors.toMap(AeRoyalties::getExcutorId, AeRoyalties::getTotalMoney));
//        }
//        Map<Long, BigDecimal> finalDepPrincipalMoneyMap = depPrincipalMoneyMap;
//        Map<Long, BigDecimal> finalExecutorMoneyMap = executorMoneyMap;
        pageInfo.getList().forEach(x -> {
//            if (x.getType().equals(NumberCst.ONE)) {
//                if (finalExecutorMoneyMap.size() > 0 && Objects.nonNull(finalExecutorMoneyMap.get(x.getExcutorId()))) {
//                    x.setRoyaltyAmount(finalExecutorMoneyMap.get(x.getExcutorId()).setScale(2, BigDecimal.ROUND_HALF_UP));
//                } else {
//                    x.setRoyaltyAmount(BigDecimal.ZERO);
//                }
//            }
//            if (x.getType().equals(NumberCst.TWO)) {
//                if (finalDepPrincipalMoneyMap.size() > 0 && Objects.nonNull(finalDepPrincipalMoneyMap.get(x.getExcutorId()))) {
//                    x.setRoyaltyAmount(finalDepPrincipalMoneyMap.get(x.getExcutorId()).setScale(2, BigDecimal.ROUND_HALF_UP));
//                } else {
//                    x.setRoyaltyAmount(BigDecimal.ZERO);
//                }
//            }
            x.setJobNumber(sUserMap.get(x.getExcutorId()));
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer create(AeQuarterlyTableDTO aeQuarterlyTableDTO) {
        if (isConditionQuery(aeQuarterlyTableDTO)) {
            AeQueryExcutionOrderDTO aeQueryExcutionOrderDTO = new AeQueryExcutionOrderDTO();
            aeQueryExcutionOrderDTO.setBeginDate(aeQuarterlyTableDTO.getBeginDate());
            aeQueryExcutionOrderDTO.setEndDate(aeQuarterlyTableDTO.getEndDate());
            aeQueryExcutionOrderDTO.setPaybackStatus(aeQuarterlyTableDTO.getPayBackStatus());
            aeQueryExcutionOrderDTO.setApprovalStatus(aeQuarterlyTableDTO.getApprovalStatus());
            aeQueryExcutionOrderDTO.setCommissionSettleStatusList(aeQuarterlyTableDTO.getCommissionSettleStatus());
            aeQueryExcutionOrderDTO.setIncomeContractCode(aeQuarterlyTableDTO.getIncomeContractCode());
            aeQueryExcutionOrderDTO.setExcuteCode(aeQuarterlyTableDTO.getExcuteCode());
            aeQuarterlyTableDTO.setExcuteIds(contractExcutionOrderService.getContractExcutionOrderByCondition(aeQueryExcutionOrderDTO));
        }
        BusinessAssert.notEmpty(aeQuarterlyTableDTO.getExcuteIds(), McnErrorCode.AE_EXCUTE_IS_NULL);
        // 检查
        check(aeQuarterlyTableDTO);
        // 根据id查询执行单
        List<ContractExcutionOrder> list = contractExcutionOrderService.getAllByIds(aeQuarterlyTableDTO.getExcuteIds());
        List<Long> executorIds = list.stream().map(ContractExcutionOrder::getExcutorId).collect(Collectors.toList());
        // 部门信息
        Map<Long, DepartmentVO> sDepartmentMap = Objects.requireNonNull(privilegeClient.getDepartmentHeadByUserIds(executorIds)).getObj();
        List<AeRoyalties> aeRoyaltiesList = new ArrayList<>();
        list.forEach(contractExecutionOrder -> {
            // 执行人提成单
            AeRoyalties executeAeRoyalties = buildAeRoyalties(contractExecutionOrder, aeQuarterlyTableDTO.getId());
            if (CommonUtil.containsKey(sDepartmentMap, contractExecutionOrder.getExcutorId())) {
                executeAeRoyalties.setDepPrincipalNameId(sDepartmentMap.get(contractExecutionOrder.getExcutorId()).getDepartmentHeadId());
                executeAeRoyalties.setDepPrincipalName(sDepartmentMap.get(contractExecutionOrder.getExcutorId()).getDepartmentHeadName());
            }
//            if (Objects.isNull(executeAeRoyalties.getDepPrincipalNameId())) {
//                executeAeRoyalties.setDepPrincipalPoint(new BigDecimal(0));
//            }
            // 有统筹人
            if (Objects.nonNull(contractExecutionOrder.getCoordinatorId())) {
                // 改为0.4
//                executeAeRoyalties.setTotalPoint(new BigDecimal("0.004"));
                // 统筹人执行单
                AeRoyalties coordinatorAeRoyalties = new AeRoyalties();
                BeanUtils.copyProperties(executeAeRoyalties, coordinatorAeRoyalties);
//                coordinatorAeRoyalties.setDepPrincipalPoint(new BigDecimal(0));
                coordinatorAeRoyalties.setAeRoyaltiesType(AeCommonEnum.AEROYALTIES_TYPE_ONE.getCode());
//                coordinatorAeRoyalties.setTotalPoint(new BigDecimal("0.001"));
                coordinatorAeRoyalties.setExcutorId(contractExecutionOrder.getCoordinatorId());
                coordinatorAeRoyalties.setExcutorName(contractExecutionOrder.getCoordinatorName());
                //coordinatorAeRoyalties.calculation(contractExecutionOrder, true);
                aeRoyaltiesList.add(coordinatorAeRoyalties);
            }
            //executeAeRoyalties.calculation(contractExecutionOrder, true);
            aeRoyaltiesList.add(executeAeRoyalties);
        });

        setJobNumber(aeRoyaltiesList);
        // 批量添加确认详情信息
        batchCreateAecutorConfirm(aeQuarterlyTableDTO, aeRoyaltiesList);
        //批量修改执行单结算状态
        if (DataStatusEnum.ZC_CONTRACT.getCode() == aeQuarterlyTableDTO.getIsDelete()) {
            batchUpdateSettleStatus(aeQuarterlyTableDTO.getExcuteIds(), CommonSettleStatusEnum.IN_SETTLEMENT.code());
        }
        return this.baseMapper.insertBatch(aeRoyaltiesList);
    }


    public void setJobNumber(List<AeRoyalties> aeRoyaltiesList) {
        List<Long> executorIdList = aeRoyaltiesList.stream().map(AeRoyalties::getExcutorId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<Long> depPrincipalNameIds = aeRoyaltiesList.stream().map(AeRoyalties::getDepPrincipalNameId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        executorIdList.addAll(depPrincipalNameIds);
        List<SUser> sUsers = Objects.requireNonNull(privilegeClient.getUserByIds(executorIdList)).getObj();
        Map<Long, SUser> sUserMap = sUsers.stream().collect(Collectors.toMap(SUser::getUserId, sUser -> sUser));
        aeRoyaltiesList.forEach(x -> {
            if (Objects.nonNull(x.getExcutorId()) && Objects.nonNull(sUserMap.get(x.getExcutorId()))) {
                x.setJobNumber(sUserMap.get(x.getExcutorId()).getJobNumber());
            }
            if (Objects.nonNull(x.getDepPrincipalNameId()) && Objects.nonNull(sUserMap.get(x.getDepPrincipalNameId()))) {
                x.setDepartmentJobNumber(sUserMap.get(x.getDepPrincipalNameId()).getJobNumber());
            }
        });
    }

    /**
     * 修改AE提成单
     *
     * @param aeRoyaltiesUpdateDTO@return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer update(AeRoyaltiesUpdateDTO aeRoyaltiesUpdateDTO) {
        Assert.notNull(aeRoyaltiesUpdateDTO.getId(), McnErrorCode.AE_ID_IS_NULL.message());
        AeRoyalties aeRoyalties = this.baseMapper.selectById(aeRoyaltiesUpdateDTO.getId());
        AeQuarterlyTable aeQuarterlyTable = aeQuarterlyTableMapper.selectById(aeRoyalties.getAeQuarterlyId());
        AeQuarterlyTableDTO aeQuarterlyTableDTO = new AeQuarterlyTableDTO();
        BeanUtils.copyProperties(aeQuarterlyTable, aeQuarterlyTableDTO);
        ContractExcutionOrder contractExcutionOrder = contractExcutionOrderService.getById(aeRoyalties.getExcuteId());
        if (Objects.isNull(contractExcutionOrder)) {
            throw new BusinessException(McnErrorCode.AE_EXCUTE_IS_NULL);
        }
        // aeRoyalties.setTotalPoint(aeRoyaltiesUpdateDTO.getTotalPoint());
        aeRoyalties.setExcutorId(aeRoyaltiesUpdateDTO.getExcutorId());
        aeRoyalties.setExcutorName(aeRoyaltiesUpdateDTO.getExcutorName());
        aeRoyalties.setDepPrincipalName(aeRoyaltiesUpdateDTO.getDepPrincipalName());
        aeRoyalties.setDepPrincipalNameId(aeRoyaltiesUpdateDTO.getDepPrincipalNameId());
        // aeRoyalties.setDepPrincipalPoint(aeRoyaltiesUpdateDTO.getDepPrincipalPoint());
        //aeRoyalties.calculation(contractExcutionOrder, false);
        List<Long> executorIds = Arrays.asList(aeRoyalties.getExcutorId(), aeRoyalties.getDepPrincipalNameId());
        List<SUser> sUsers = Objects.requireNonNull(privilegeClient.getUserByIds(executorIds)).getObj();
        Map<Long, SUser> sUserMap = sUsers.stream().collect(Collectors.toMap(SUser::getUserId, sUser -> sUser));
        if(CommonUtil.containsKey(sUserMap, aeRoyalties.getExcutorId())) {
            aeRoyalties.setJobNumber(sUserMap.get(aeRoyalties.getExcutorId()).getJobNumber());
        }
        if(CommonUtil.containsKey(sUserMap, aeRoyalties.getDepPrincipalNameId())) {
            aeRoyalties.setDepartmentJobNumber(sUserMap.get(aeRoyalties.getDepPrincipalNameId()).getJobNumber());
        }
        //批量如果修改了部门负责人或者执行人添加确认详情
        batchCreateAecutorConfirm(aeQuarterlyTableDTO, Collections.singletonList(aeRoyalties));
        aeRoyalties.ignore();
        return this.baseMapper.updateById(aeRoyalties);
    }

    @Override
    public BigDecimal getTotalMoney(Long aeQuarterlyId) {
        return this.baseMapper.getTotalMoney(aeQuarterlyId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchDelete(List<Long> ids) {
        List<AeRoyalties> list =
                this.baseMapper.selectList(Wrappers.lambdaQuery(AeRoyalties.class).in(AeRoyalties::getId, ids));
        list.forEach(x -> x.setIsDelete(DataStatusEnum.YSC_CONTRACT.getCode()));
        List<Long> executeIds = list.stream().map(AeRoyalties::getExcuteId).collect(Collectors.toList());
        // 先修改状态
        this.updateBatchById(list);
        // 再判断是否要修改结算状态
        List<Long> mapperExecuteIds = this.baseMapper.getExcuteIds(executeIds);
        Map<Long, Long> longMap =
                mapperExecuteIds.stream().collect(Collectors.toMap(Long::longValue, Long::longValue, (key1, key2) -> key2));
        List<Long> result = new ArrayList<>();
        executeIds.forEach(x -> {
            if (!longMap.containsKey(x)) {
                result.add(x);
            }
        });
        batchUpdateSettleStatus(result, CommonSettleStatusEnum.UNSETTLED.code());
        return Boolean.TRUE;
    }

    @Override
    public void exportExcel(AeRoyaltiesExportDTO aeRoyaltiesExportDTO, HttpServletResponse response) throws Exception {
        Assert.notNull(aeRoyaltiesExportDTO.getAeQuarterlyId(), McnErrorCode.AE_QUARTERLY_ID_IS_NULL.message());
        AeQuarterlyTable aeQuarterlyTable = aeQuarterlyTableMapper.selectById(aeRoyaltiesExportDTO.getAeQuarterlyId());
        String aeQuarterlyCode = CommonUtil.getAeQuarterlyCode(aeQuarterlyTable.getAeQuarterlyCode());
        AeRoyaltiesDTO aeRoyaltiesDTO = new AeRoyaltiesDTO();
        BeanUtil.copyProperties(aeRoyaltiesExportDTO, aeRoyaltiesDTO);
        aeRoyaltiesDTO.setPageSize(Integer.MAX_VALUE);
        PageInfo<AeRoyaltiesVoV2> pageInfo = PageInfo.toPageInfo(this.baseMapper.getContractExcutionOrders(new Page<>(aeRoyaltiesDTO.getPageNum(), aeRoyaltiesDTO.getPageSize()), aeRoyaltiesDTO));
        if (CollectionUtils.isNotEmpty(pageInfo.getList())) {
            this.assembleExportData(pageInfo.getList());
        }
        //v2.1版本导出字段更改
        String fileName = aeQuarterlyCode + "AE执行提成单.xlsx";
        ExcelUtils.exportExcel(CommonUtil.defaultList(pageInfo.getList()), "AE提成", AeRoyaltiesVoV2.class, fileName, response);
    }

    /**
     * 发送提成单
     *
     * @param aeDetailDTO {@link AeDetailDTO}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendCommission(AeDetailDTO aeDetailDTO) {
        Assert.notNull(aeDetailDTO.getId(), McnErrorCode.AE_ID_IS_NULL.message());
        Assert.notNull(aeDetailDTO.getType(), McnErrorCode.PARAM_ERROR.message());
        AeRoyalties aeRoyalties = this.baseMapper.selectById(aeDetailDTO.getId());
        Assert.notNull(aeRoyalties, McnErrorCode.AE_EXCUTE_IS_NULL.message());
        AeQuarterlyTable aeQuarterlyTable = aeQuarterlyTableMapper.selectById(aeRoyalties.getAeQuarterlyId());
        String aeQuarterlyCode = CommonUtil.getAeQuarterlyCode(aeQuarterlyTable.getAeQuarterlyCode());
        if (AeCommonEnum.IS_EXCUTOR.getCode().equals(aeDetailDTO.getType())) {
            approvalFlowService.sendAeNotify(aeQuarterlyTable.getTenantId(), aeQuarterlyTable.getId(),
                    aeQuarterlyTable.getAeQuarterlyExcuteCode(), aeQuarterlyCode,
                    ApprovalEnum.AE_COMMISSION, true, aeRoyalties.getExcutorId(), aeRoyalties.getExcutorName(),
                    AeCommonEnum.IS_EXCUTOR.getCode());
        }
        if (AeCommonEnum.IS_DEPPRINCIPALNAMEID.getCode().equals(aeDetailDTO.getType())) {
            approvalFlowService.sendAeNotify(aeQuarterlyTable.getTenantId(), aeQuarterlyTable.getId(),
                    aeQuarterlyTable.getAeQuarterlyExcuteCode(), aeQuarterlyCode,
                    ApprovalEnum.AE_DEPARTMENT, true, aeRoyalties.getDepPrincipalNameId(),
                    aeRoyalties.getDepPrincipalName(), AeCommonEnum.IS_DEPPRINCIPALNAMEID.getCode());
        }
        aeRoyalties.ignore();
        this.baseMapper.updateById(aeRoyalties);
    }

    /**
     * 构建AE提成单
     *
     * @param contractExcutionOrder {@link ContractExcutionOrder}
     * @param aeQuarterlyId         {@link Long}
     * @return {@link AeRoyalties}
     */
    private AeRoyalties buildAeRoyalties(ContractExcutionOrder contractExcutionOrder,
                                         Long aeQuarterlyId) {
        // 执行人提成单
        AeRoyalties aeRoyalties = new AeRoyalties();
        aeRoyalties.setExcuteId(contractExcutionOrder.getId());
        aeRoyalties.setExcuteCode(contractExcutionOrder.getExcuteCode());
        aeRoyalties.setAeRoyaltiesType(AeCommonEnum.AEROYALTIES_TYPE_ZERO.getCode());
//        aeRoyalties.setTotalPoint(new BigDecimal("0.005"));
//        aeRoyalties.setDepPrincipalPoint(new BigDecimal("0.001"));
        aeRoyalties.setAeQuarterlyId(aeQuarterlyId);
        aeRoyalties.setExcutorId(contractExcutionOrder.getExcutorId());
        aeRoyalties.setExcutorName(contractExcutionOrder.getExcutorName());
        aeRoyalties.setIsDelete(DataStatusEnum.ZC_CONTRACT.getCode());
        aeRoyalties.setIsInvalid(DataStatusEnum.ZC_CONTRACT.getCode());
        aeRoyalties.setBrandName(contractExcutionOrder.getBrandName());
        aeRoyalties.setProductName(contractExcutionOrder.getProductName());
        return aeRoyalties;
    }

    /**
     * 检查参数
     *
     * @param aeQuarterlyTableDTO {@link AeQuarterlyTableDTO}
     */
    private void check(AeQuarterlyTableDTO aeQuarterlyTableDTO) {
        Assert.isTrue(StringUtils.isNotBlank(aeQuarterlyTableDTO.getAeQuarterlyCode()),
                McnErrorCode.AE_QUARTERLY_CODE_IS_NULL.message());
        List<String> list = this.baseMapper.checkIsRepeat(aeQuarterlyTableDTO.getExcuteIds(), null);
        if (!CollectionUtils.isEmpty(list)) {
            throw new BusinessException(McnErrorCode.AE_EXCUTE_CANNOT_BE_REPEATED.code(),
                    String.format(McnErrorCode.AE_EXCUTE_CANNOT_BE_REPEATED.message(), CommonUtil.listToString(list, ',')));
        }
        list = this.baseMapper.checkIsRepeatById(aeQuarterlyTableDTO.getExcuteIds(), aeQuarterlyTableDTO.getId());
        if (!CollectionUtils.isEmpty(list)) {
            throw new BusinessException(McnErrorCode.AE_EXCUTE_CANNOT_BE_REPEATED.code(),
                    String.format(McnErrorCode.AE_EXCUTE_CANNOT_BE_REPEATED.message(), CommonUtil.listToString(list, ',')));
        }

    }

    /**
     * 判断是否是条件查询
     *
     * @return {@link Boolean}
     */
    private boolean isConditionQuery(AeQuarterlyTableDTO aeQuarterlyTableDTO) {
        Assert.notNull(aeQuarterlyTableDTO.getIsConditionQuery(), McnErrorCode.PARAM_ERROR.message());
        return aeQuarterlyTableDTO.getIsConditionQuery().equals(AeCommonEnum.IS_CONDITION_QUERY.getCode());
    }

    /**
     * 判断是否已确认
     *
     * @param aeRoyaltiesDTO   {@link AeRoyaltiesDTO}
     * @param aeQuarterlyTable {@link AeQuarterlyTable}
     */
    // private void isConfirmed(AeRoyaltiesDTO aeRoyaltiesDTO, AeQuarterlyTable aeQuarterlyTable) {
    //     List<AeExcutorConfirm> list = aeExcutorConfirmMapper.selectList(Wrappers.lambdaQuery(AeExcutorConfirm.class)
    //             .eq(AeExcutorConfirm::getAeQuarterlyId, aeQuarterlyTable.getId())
    //             .eq(AeExcutorConfirm::getExcutorId, aeRoyaltiesDTO.getExcutorId())
    //             .eq(AeExcutorConfirm::getType, aeRoyaltiesDTO.getType())
    //             .eq(AeExcutorConfirm::getIsConfirmed, AeCommonEnum.IS_CONFIRM.getCode()));
    //     if (CollectionUtils.isEmpty(list)) {
    //         aeQuarterlyTable.setStatus(AeQuarterlyTypeEnum.YFS_CONTRACT.getCode());
    //     } else {
    //         aeQuarterlyTable.setStatus(AeQuarterlyTypeEnum.YQR_CONTRACT.getCode());
    //     }
    // }

    /**
     * 批量添加确认详情信息
     *
     * @param aeQuarterlyTableDTO {@link AeQuarterlyTableDTO}
     * @param aeRoyaltiesList     {@link List<AeRoyalties>}
     */
    private void batchCreateAecutorConfirm(AeQuarterlyTableDTO aeQuarterlyTableDTO, List<AeRoyalties> aeRoyaltiesList) {
        //if (aeQuarterlyTableDTO.getStatus() > AeQuarterlyTypeEnum.NEW_CONTRACT.getCode()) {
        List<AeRoyalties> commissionDetails = aeRoyaltiesList.stream()
                .filter(CommonUtil.distinctByKey(AeRoyalties::getExcutorId)).collect(Collectors.toList());
        List<AeRoyalties> departmentDetails =
                aeRoyaltiesList.stream().filter(s -> Objects.nonNull(s.getDepPrincipalNameId()))
                        .filter(CommonUtil.distinctByKey(AeRoyalties::getDepPrincipalNameId))
                        .collect(Collectors.toList());
        aeExcutorConfirmService.batchCreate(new AeExcutorConfirmNewDTO(aeQuarterlyTableDTO.getId(),
                commissionDetails.stream().map(AeRoyalties::getExcutorId).collect(Collectors.toList()),
                AeCommonEnum.IS_EXCUTOR.getCode()));
        aeExcutorConfirmService.batchCreate(new AeExcutorConfirmNewDTO(aeQuarterlyTableDTO.getId(),
                departmentDetails.stream().map(AeRoyalties::getDepPrincipalNameId).collect(Collectors.toList()),
                AeCommonEnum.IS_DEPPRINCIPALNAMEID.getCode()));
        //}
    }


    /**
     * 批量更新执行单提成结算状态
     *
     * @param executeIds             {@link List<Long>}
     * @param commissionSettleStatus {@link Integer}
     */
    private void batchUpdateSettleStatus(List<Long> executeIds, Integer commissionSettleStatus) {
        if (CollectionUtils.isEmpty(executeIds)) {
            return;
        }
        contractExcutionOrderService.batchUpdateSettleStatus(executeIds, commissionSettleStatus);
    }


}
